package com.sdkj.dspservice;

import com.fasterxml.jackson.databind.JsonNode;
import com.sdkj.dspservice.common.base.entity.BaseResult;
import com.sdkj.dspservice.common.config.ProjectConfig;
import com.sdkj.dspservice.common.react.AntdProResult;
import com.sdkj.dspservice.common.utils.*;
import com.sdkj.dspservice.common.utils.dsp.CdpUtils;
import com.sdkj.dspservice.modules.sys.entity.User;
import com.sdkj.dspservice.modules.sys.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * 业务表Controller
 *
 * @author tm
 * @version 2020/12/28 18:54
 */

@Controller
public class HomeController {

    /**
     * 因为cdp平台用户无法
     */
    private static final String CDP_USER_PASSWORD = "123456";

    @Autowired
    private UserService userService;
    @Autowired
    private ProjectConfig projectConfig;
    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("/index")
    public String index() {
        return "index";
    }

    /**
     * 登出
     * @param session
     * @return
     */
    @RequestMapping("/cdpLogout")
    public AntdProResult cdpLogout(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        // 清除redis中，登录模块的所有缓存
        RedisUtils redisUtils = new RedisUtils(redisTemplate);
        redisUtils.deleteModule(RedisUtils.LOGIN_MODULE);
        return new AntdProResult();
    }

    @RequestMapping("/cdpLogin")
    public String cdpLogin(User user, HttpServletRequest request) {
        // 获取运行模式
        String springProfilesActive = SpringContextHolder.getApplicationContext().getEnvironment().getActiveProfiles()[0];
        String cdpUserId = null;
        if("dev".equals(springProfilesActive)){
            // 获取cdpUserId，并且加密，插入user中
            if(StringUtils.isNotBlank(user.getCdpUserId())){
                cdpUserId = String.valueOf(HashIdsUtils.decode(user.getCdpUserId())[0]);
            }
        }else if("pro".equals(springProfilesActive)){
            // 获取cdpUserId，并且加密，插入user中
            cdpUserId = request.getHeader("x-user-id");
        }
        System.out.println("*******************cdpUserId：" + cdpUserId + "*******************************");
        if(StringUtils.isNotBlank(cdpUserId) && StringUtils.isNumeric(cdpUserId)){
            user.setCdpUserId(HashIdsUtils.encode(Integer.parseInt(cdpUserId)));
        }else {
            System.out.println("*******************cdpUserId不存在或者不是一个数字*******************************");
        }
        // 默认为跳转到cdp登录页，除非校验通过
        String result = "redirect:https://rp.jx139.com/login";
        System.out.println("**********************进入三方登录模式***********************");
        // 三方登录模式
        // 判断是否传入cdp用户ID
        if (StringUtils.isNotBlank(user.getCdpUserId())) {
            // 从数据库中根据该ID获取用户
            User loginUser = userService.getByCdpUserId(user.getCdpUserId());
            // 是否有用户
            boolean isHaveUser = true;
            // 如果user为null，则说明本系统未同步用户，则进行同步重新判断
            if (loginUser == null) {
                // 用户同步
                userSynchronization();
                // 重新从数据库中获取用户
                loginUser = userService.getByCdpUserId(user.getCdpUserId());
                // 此时user还为空则，该用户不存在
                if (loginUser == null) {
                    System.out.println("**************三方登录，用户经过同步之后不存在！****************");
                    isHaveUser = false;
                }
            }
            // 用户校验
            if (isHaveUser) {
                // 手动插入密码
                loginUser.setPassword(CDP_USER_PASSWORD);
                AntdProResult r = userAuthentication(loginUser, new AntdProResult());
                if(r.getSuccess()){
                    System.out.println("************************校验成功！************************");
                    // 校验成功，则进入index页面
                    result = "redirect:/";
                }
            }
        } else {
            System.out.println("************************用户ID为空！************************");
        }
        return result;
    }

    /**
     * 用户认证
     *
     * @param user
     */
    private AntdProResult userAuthentication(User user, AntdProResult result) {
        //用户认证信息
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(
                user.getLoginName(),
                user.getPassword()
        );
        try {
            //进行验证，这里可以捕获异常，然后返回对应信息
            subject.login(usernamePasswordToken);
        } catch (UnknownAccountException e) {
            System.out.println("************************用户名不存在！***********************");
            result.error(AntdProResult.VALIDATOR_ERROR, "用户名不存在！");
        } catch (AuthenticationException e) {
            System.out.println("***********************账号或密码错误！**********************");
            result.error(AntdProResult.VALIDATOR_ERROR, "账号或密码错误！");
        } catch (Exception e){
            System.out.println("***********************用户校验位置错误！**********************");
            result.error(AntdProResult.VALIDATOR_ERROR, "用户校验位置错误！");
        }
        return result;
    }

    /**
     * 三方登录时，用户同步
     *
     * @param
     */
    private void userSynchronization() {
        System.out.println("************************用户同步11111！**************************");
        BaseResult result = CdpUtils.graphql("{\"query\":\"query MyQuery {\\n  version\\n  dataCenterRoles {\\n    id\\n    description\\n    isRoot\\n    isSystem\\n    isTechSupport\\n    name\\n    members {\\n      id\\n      identity\\n      lastVisitAt\\n      name\\n      phoneNumber\\n      source\\n      email\\n      creator\\n      createdAt\\n      avatar\\n    }\\n  }\\n}\\n\",\"variables\":null,\"operationName\":\"MyQuery\"}");
        JsonNode roleListNode = JsonUtils.getJsonNode(String.valueOf(result.getData()), "data-dataCenterRoles");
        // 此时jsonNode为角色列表
        int i = 0;
        while (roleListNode.has(i)) {
            JsonNode roleNode = roleListNode.get(i);
            if (roleNode != null) {
                String roleId = JsonUtils.getValue(roleNode, "id");
                String roleName = JsonUtils.getValue(roleNode, "name");
                // roleNode中的members为用户列表
                if (roleNode.has("members")) {
                    JsonNode userListNode = roleNode.get("members");
                    if (userListNode != null) {
                        int j = 0;
                        while (userListNode.has(j)) {
                            JsonNode userNode = userListNode.get(j);
                            String cdpUserId = JsonUtils.getValue(userNode, "id");
                            String userName = JsonUtils.getValue(userNode, "name");
                            String userPhoneNumber = JsonUtils.getValue(userNode, "phoneNumber");
                            String userIdentity = JsonUtils.getValue(userNode, "identity");
                            String userEmail = JsonUtils.getValue(userNode, "email");
                            // 查询数据库是否已存在该用户
                            User oldUser = userService.getByCdpUserId(cdpUserId);
                            // 不存在（或手机号更换了）则同步
                            if(oldUser == null){
                                // 同步用户
                                User user = new User();
                                user.setCdpUserId(cdpUserId);
                                user.setPassword(CDP_USER_PASSWORD); // 默认密码123456
                                user.setPhone(userPhoneNumber);
                                user.setMobile(userPhoneNumber);
                                user.setEmail(userEmail);
                                user.setLoginName(userIdentity);
                                user.setName(userName);
                                userService.saveOrUpdate(user);
                            }else {
                                System.out.println("*********************oldUserMobile：" + oldUser.getMobile() + "******************");
                                System.out.println("*********************userPhoneNumber：" + userPhoneNumber + "******************");
                                if(!userPhoneNumber.equals(oldUser.getMobile())){
                                    oldUser.setMobile(userPhoneNumber);
                                    oldUser.setPhone(userPhoneNumber);
                                    userService.saveOrUpdate(oldUser);
                                }
                            }
                            ++j;
                        }
                    }
                }
            }
            ++i;
        }
    }

}
